package com.hjj.springboot.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hjj.springboot.entity.Product;
import com.hjj.springboot.entity.R;
import com.hjj.springboot.entity.Recipe;
import com.hjj.springboot.entity.RecipeDetail;
import com.hjj.springboot.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/recipe")
public class RecipeController {

    @Autowired
    private IProductService productService;

    @Autowired
    private IRecipeService recipeService;

    @Autowired
    private IRecipeDetailService recipeDetailService;


    @PostMapping("/recommend/list")
    public R recommendList(@RequestParam List<Integer> pIds) {

        // 0. 检查pIds是否为空
        if (pIds == null || pIds.isEmpty()) {
            return R.error("未选择食材");
        }

        // 1. 获取所选食材涉及的菜谱ID
        List<Integer> targetMids = recipeDetailService.listObjs(
                new QueryWrapper<RecipeDetail>()
                        .select("DISTINCT mid")
                        .in("pid", pIds),
                o -> (Integer) o
        );

        if (targetMids.isEmpty()) {
            return R.error("所选食材暂无菜谱信息");
        }

        // 2. 查询推荐食材ID并按出现次数排序（使用分页）
        QueryWrapper<RecipeDetail> queryWrapper = new QueryWrapper<RecipeDetail>()
                .select("pid, COUNT(pid) AS count")
                .in("mid", targetMids)
                .notIn("pid", pIds)
                .groupBy("pid")
                .orderByDesc("count");

        Page<RecipeDetail> page = new Page<>(1, 8);
        List<Integer> recommendedPids = recipeDetailService.page(page, queryWrapper)
                .getRecords()
                .stream()
                .map(RecipeDetail::getPid)
                .collect(Collectors.toList());

        if (recommendedPids.isEmpty()) {
            return R.error("暂无相关推荐菜谱");
        }

        // 3. 获取推荐食材详情并保持顺序
        List<Product> recommendedProducts = productService.listByIds(recommendedPids)
                .stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 根据recommendedPids顺序排序（确保数据库查询保持顺序）
        Map<Integer, Product> productMap = recommendedProducts.stream()
                .collect(Collectors.toMap(Product::getId, Function.identity()));
        recommendedProducts = recommendedPids.stream()
                .map(productMap::get)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        HashMap<String, Object> map = new HashMap<>();
        map.put("recommendedProducts", recommendedProducts);
        return R.ok(map);
    }

    @GetMapping("/list")
    public R list() {
        // 1. 查询所有菜谱
        List<Recipe> recipes = recipeService.list();
        if (recipes.isEmpty()) {
            return R.ok(Collections.emptyMap());
        }

        // 2. 批量查询关联的菜谱详情（1次查询）
        List<Integer> recipeIds = recipes.stream()
                .map(Recipe::getId)
                .collect(Collectors.toList());

        Map<Integer, List<RecipeDetail>> detailsMap = recipeDetailService
                .list(new QueryWrapper<RecipeDetail>().in("mid", recipeIds))
                .stream()
                .collect(Collectors.groupingBy(RecipeDetail::getMid));

        // 3. 批量查询所有食材（1次查询）
        Set<Integer> productIds = detailsMap.values().stream()
                .flatMap(List::stream)
                .map(RecipeDetail::getPid)
                .collect(Collectors.toSet());

        Map<Integer, Product> productMap = productService.listByIds(productIds)
                .stream()
                .collect(Collectors.toMap(Product::getId, Function.identity()));

        // 4. 组装数据
        recipes.forEach(recipe -> {
            List<RecipeDetail> details = detailsMap.getOrDefault(recipe.getId(), Collections.emptyList());
            details.forEach(detail ->
                    detail.setProduct(productMap.get(detail.getPid()))
            );
            recipe.setRecipeDetailList(details);
        });

        HashMap<String, Object> map = new HashMap<>();
        map.put("recipes", recipes);
        return R.ok(map);
    }
}
